package com.msx.user.service.impl;

import com.msx.constants.IsDeleteEnum;
import com.msx.pojo.Identity;
import com.msx.pojo.User;
import com.msx.user.mapper.IdentityMapper;
import com.msx.user.mapper.UserMapper;
import com.msx.user.service.task.identityAuthTask;
import com.msx.user.service.task.identityLiveTask;
import com.msx.user.service.task.identityUpdateTask;
import com.msx.util.ResponseResult;
import com.msx.util.StatusCode;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
@Log4j2
public class UserIdentityHome {
    @Autowired
    private IdentityService identityService;

    @Autowired
    private IdentityMapper identityMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    //自定义线程池
    private ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(24,44,
                    1L, TimeUnit.SECONDS,new LinkedBlockingDeque<>(200));

    /**
     *总身份验证
     * @param name
     * @param frontImage
     * @param backImage
     * @param liveImage
     * @return
     */

    public ResponseResult UserIdentityHome(
                                    String id,
                                    String name,
                                    String identitycode,
                                    String frontImage,
                                    String backImage,
                                    String liveImage
                                   ){

        try {

            //创建正面验证线程
            identityAuthTask authTask = new identityAuthTask(name,identitycode,frontImage,identityService);
            //提交线程
            Future<Boolean> submit1 =threadPoolExecutor.submit(authTask);

            //活体认证
            //String baseLiveImage = Base64.getEncoder().encodeToString(liveImage.getBytes());
            identityLiveTask liveAuthTask = new identityLiveTask(backImage,identityService);
            Future<Boolean> submit2= threadPoolExecutor.submit(liveAuthTask);

            //地址
            identityUpdateTask updateTask = new identityUpdateTask(frontImage,backImage,liveImage,identityService);
            Future<Map<String, String>> submit3 = threadPoolExecutor.submit(updateTask);

            //获取线程状态
            Boolean t1 = submit1.get();
            Boolean t2 = submit2.get();
            Map<String, String> t3 = submit3.get();
            //打印线程状态
            log.info("线程状态:");
            log.info("t1:"+t1);
            log.info("t2:"+t2);
            log.info("t3:"+t3.size());

            //成功放入redis
            if (t1){
                redisTemplate.opsForValue().set(identitycode+id,"ok",5,TimeUnit.MINUTES);
            }
            if (t2){
                redisTemplate.opsForValue().set(backImage+id,"ok",5,TimeUnit.MINUTES);
            }
            //获取redis结果
            String ox = (String) redisTemplate.opsForValue().get(identitycode + id);
            String ol = (String) redisTemplate.opsForValue().get(backImage + id);


            if (!StringUtils.isBlank(ox)) {t1=true;}
            if (!StringUtils.isBlank(ol)) {t2=true;}


            //如果三个线程都成功 进行修改
            if (t1 && t2 && t3.size()>0){
                log.info("线程执行成功");
                //获取修改状态
                Boolean update = update(t3, name, identitycode, id);
               //判断状态
                if (!update){
                    return new ResponseResult().error(StatusCode.ERROR,"认证状态修改失败");
                }
                return new ResponseResult().success("恭喜您认证成功!");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseResult().error(StatusCode.ERROR,"异常") ;
        }

        return new ResponseResult().error(StatusCode.ERROR,"认证失败,请重新认证!");

    }

    /**
     * 添加信息
     * 修改状态
     * @param map
     * @param name
     * @param code
     * @param id
     */
    @Transactional
    public Boolean update(Map<String,String> map,String name,String code,String id){
        Boolean flag = true;
        Identity identity = new Identity();
        identity.setIdentityFront(map.get("front"));
        identity.setIdentityBack(map.get("bank"));
        identity.setLivingCertification(map.get("live"));
        identity.setIdentityCode(code);
        identity.setCreateTime(new Date());
        identity.setName(name);
        identity.setIsDelete(String.valueOf(IsDeleteEnum.OK.getCode()));
        identity.setUserId(Integer.valueOf(id));

        log.info("身份认证表添加:");
        log.info(identity);
        try {
            identityMapper.insertSelective(identity);
        } catch (Exception e) {
            e.printStackTrace();
            flag=false;
        }


        log.info("用户身份认证表修改:");
        User user = new User();
        user.setId(Integer.valueOf(id));
        user.setUserAuthentication(String.valueOf(IsDeleteEnum.ERROR.getCode()));
        log.info("修改信息:"+user);
        try {
            userMapper.updateByPrimaryKeySelective(user);
        } catch (Exception e) {
            e.printStackTrace();
            flag=false;
        }
        log.info("用户身份认证修改完毕");
        return flag;
    }

    //根据userid查询信息
    public ResponseResult findById(String uid){

        //查询
        Example example = new Example(Identity.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",uid);
        List<Identity> identities = identityMapper.selectByExample(example);

        //判断是否为空
        if (identities.size()==0){
            return new ResponseResult().error(StatusCode.ERROR,"没有绑定身份信息");
        }

        return new ResponseResult().success(identities.get(identities.size()-1));
    }

}
